import { Scene, Physics, GameObjects, Time, Math } from "phaser";
import { Snowman } from "./main/Snowman";
import { Player } from "./main/Player";
import { Snowball } from "./main/Snowball";

interface Track {
    snowmanBig: Snowman; // 大雪人
    snowmanSmall: Snowman; // 小雪人
    playerBalls: Physics.Arcade.Group; // 玩家雪球
    snowmanBalls: Physics.Arcade.Group; // 雪人雪球
    y: number; // 轨道y坐标
}

// 场景元素
let scoreText: GameObjects.Text;
let highScoreText: GameObjects.Text;
let controls: GameObjects.Image;

let player: Player;
let tracks: Track[];

// 场景数据
let score: number;
let highScore: number;

export const trackY = [196, 376, 536, 700];

// 计时器
let scoreTimer: Time.TimerEvent;
let startTimers: Time.TimerEvent[] = [];

export class Main extends Scene {
    constructor() {
        super("Main");
    }
    create() {
        // 背景
        this.add.image(512, 384, "background");
        this.add.image(0, 0, "overlay").setOrigin(0);
        this.add.image(16, 0, "sprites", "panel-score").setOrigin(0);
        this.add.image(1024 - 16, 0, "sprites", "panel-best").setOrigin(1, 0);

        // 初始化轨道
        tracks = [];
        for (let i = 0; i < trackY.length; i++) {
            // 企鹅蛋
            this.physics.add.image(1024, trackY[i] - 10, "sprites", "nest").setOrigin(1, 1);
            // 添加轨道
            tracks.push({
                y: trackY[i],
                snowmanBig: new Snowman(this, "Big", trackY[i], i),
                snowmanSmall: new Snowman(this, "Small", trackY[i], i),
                playerBalls: this.physics.add.group({
                    frameQuantity: 8,
                    key: "sprites",
                    frame: "snowball2",
                    active: false,
                    visible: false,
                    classType: Snowball,
                }),
                snowmanBalls: this.physics.add.group({
                    frameQuantity: 8,
                    key: "sprites",
                    frame: "snowball3",
                    active: false,
                    visible: false,
                    classType: Snowball,
                }),
            });
        }

        // 创建玩家
        player = new Player(this);

        // 控制说明
        controls = this.add.image(512, 384, "sprites", "controls");

        // 分数
        score = 0;
        highScore = this.registry.get("highScore");
        scoreText = this.add.text(140, 2, String(score), {
            fontFamily: "Arial",
            fontSize: 32,
            color: "#ffffff",
        });
        highScoreText = this.add.text(820, 2, String(highScore), {
            fontFamily: "Arial",
            fontSize: 32,
            color: "#ffffff",
        });
        // 注册事件
        this.addEvent();
    }
    // 注册事件
    addEvent() {
        // 雪球和雪人撞击事件
        for (let { playerBalls, snowmanBalls, snowmanBig, snowmanSmall } of tracks) {
            this.physics.add.overlap(playerBalls, snowmanBalls, this.hitSnowball, null, this);
            this.physics.add.overlap(playerBalls, snowmanSmall, this.hitSnowman, null, this);
            this.physics.add.overlap(playerBalls, snowmanBig, this.hitSnowman, null, this);
        }
        // 游戏开始事件
        this.input.keyboard.once("keydown-SPACE", this.start, this);
        this.input.keyboard.once("keydown-UP", this.start, this);
        this.input.keyboard.once("keydown-DOWN", this.start, this);
    }
    // 游戏开始
    start() {
        // 移除所有键盘事件
        this.input.keyboard.removeAllListeners();

        // 隐藏控制说明
        this.tweens.add({
            targets: controls,
            y: 700,
            alpha: 0,
            duration: 500,
            ease: "Power2",
        });

        // 每隔1s分数+1
        scoreTimer = this.time.addEvent({
            delay: 1000,
            callback: () => {
                score++;
                scoreText.setText(String(score));
            },
            callbackScope: this,
            repeat: -1,
        });

        // 延迟开启雪人走路
        for (let track of tracks) {
            const delay = Math.Between(1000, 8000);
            startTimers.push(
                this.time.addEvent({
                    delay: delay,
                    callback: () => {
                        track.snowmanSmall.start();
                    },
                }),
                this.time.addEvent({
                    delay: delay * 3,
                    callback: () => {
                        track.snowmanBig.start();
                    },
                })
            );
        }
    }
    // 击中雪球
    hitSnowball(ball1, ball2) {
        (ball1 as Snowball).disableBody(true, true);
        (ball2 as Snowball).disableBody(true, true);
    }
    // 击中雪人
    hitSnowman(snowman, ball) {
        (ball as Snowball).disableBody(true, true);
        (snowman as Snowman).hited();
    }
    // 投掷玩家雪球
    throwPlayerBall() {
        // 根据玩家所处轨道
        let track = tracks[player.trackIndex];
        // 获取雪球，发射雪球
        let snowball: Snowball = track.playerBalls.getFirstDead();
        snowball?.fire(player.x, track.y);
    }
    // 投掷雪人雪球
    throwSnowmanBall(trackIndex: number, x: number) {
        // 根据玩家所处轨道
        let track = tracks[trackIndex];
        // 获取雪球，发射雪球
        let snowball: Snowball = track.snowmanBalls.getFirstDead();
        snowball?.fire(x, track.y);
    }
    // 游戏结束
    gameOver() {
        // 游戏结束提示
        this.tweens.add({
            targets: this.add.image(512, 700, "gameover").setAlpha(0),
            y: 384,
            alpha: 1,
            duration: 500,
            ease: "Power2",
        });

        // 停止玩家
        player.stop();
        for (let track of tracks) {
            // 停止雪人
            track.snowmanBig.stop();
            track.snowmanSmall.stop();
            // 停止雪球
            for (let snowball of track.playerBalls.getChildren()) {
                (snowball as Snowball).disableBody(true);
            }
            for (let snowball of track.snowmanBalls.getChildren()) {
                (snowball as Snowball).disableBody(true);
            }
        }

        // 游戏结束音效
        this.sound.stopAll();
        this.sound.play("gameover");

        // 清除分数计时器
        scoreTimer.remove();
        // 清除开始计时器
        for (let timer of startTimers) {
            timer.remove();
        }

        // 新最高纪录
        if (score > highScore) {
            highScoreText.setText("NEW!");
            this.registry.set("highScore", score);
        }

        // 任意鼠标点击，重启Menu场景
        this.input.once("pointerdown", () => this.scene.start("Menu"), this);
    }
}
